package com.lin.controller;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.lin.constant.BookConstants;
import com.lin.entity.ErrorResponse;
import com.lin.entity.R;
import com.lin.entity.dto.BookDTO;
import com.lin.entity.dto.UpdateBookDTO;
import com.lin.entity.query.BookQuery;
import com.lin.entity.vo.BookVO;
import com.lin.entity.vo.PageVO;
import com.lin.exception.*;
import com.lin.service.IBookService;
import jakarta.annotation.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;


@RestController
@RequestMapping("/books")
public class BookController {
    @Resource
    private IBookService bookService;

    /**
     * 新增图书
     * @param bookDTO 图书信息
     * @return R
     */
    @PostMapping
    public R addBook(@RequestBody BookDTO bookDTO) {
        return bookService.addBook(bookDTO);
    }

    /**
     * 更新图书信息
     * @param updateBookDTO 图书信息
     * @return R
     */
    @PutMapping
    public R updateBook(@RequestBody UpdateBookDTO updateBookDTO) {
        return bookService.updateBook(updateBookDTO);
    }

    /**
     * 获取图书信息--先查询Redis中是否有对应数据, 存在直接返回
     * 不存在则查询数据库并添加到Redis中
     * @param bookId 图书ID
     * @return R
     */
    @GetMapping("/{bookId}")
    public R getBookById(@PathVariable("bookId") Integer bookId) {
        if (bookId == null)
            throw new BookIdInvalidException("图书ID为空");

        BookVO bookVO = null;

        try {
            bookVO = bookService.getBookById(bookId);
        } catch (JsonProcessingException e) {
            R.error("查询图书信息失败", null);
        }

        if (bookVO == null) return
                R.failed("id不能为null", null);

        return R.ok("查询成功", bookVO);
    }


    /**
     * 基础分页查询图书信息
     * 先查询Redis中是否有对应数据, 存在直接返回
     * 不存在则查询数据库并添加到Redis中
     * @param page 页码
     * @param pageSize 每页条数
     * @return R
     */
    @GetMapping
    public R getBookList(@RequestParam Integer page, @RequestParam Integer pageSize) {
        PageVO<BookVO> bookList = null;

        try {
            bookList = bookService.getBookList(page, pageSize);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        if (bookList != null)
            return R.ok("查询成功", bookList);
        return R.failed("查询失败", null);
    }

    /**
     * 条件分页查询图书信息
     * 先查看Redis中是否有对应数据, 存在直接返回
     * 不存在则查询数据库并添加到Redis中
     * @param bookQuery 查询条件
     * @return R
     */
    @GetMapping("/page")
    public R getBooksPage(@RequestBody BookQuery bookQuery){
        PageVO<BookVO> booksPage = null;

        try {
            booksPage = bookService.getBooksPage(bookQuery);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        if (booksPage != null)
            return R.ok("查询成功", booksPage);
        return R.failed("查询失败", null);
    }

    /**
     * 逻辑删除图书
     * @param id 图书ID
     * @return R
     */
    @PostMapping("/{id}")
    public R logicDeleteBook(@PathVariable Integer id) {
        if (id == null)
            throw new BookIdInvalidException("图书ID为空");

        boolean status =  bookService.logicDeleteBook(id);

        if (status)
            return R.ok("删除成功", null);
        return R.failed("删除失败", null);
    }


    /**
     * 处理BookStatusException异常
     * @param ex 异常
     * @return 响应实体
     */
    @ExceptionHandler(BookStatusException.class)
    public ResponseEntity<ErrorResponse> handleBookStatusException(BookStatusException ex) {
        ErrorResponse errorResponse = new ErrorResponse(BookConstants.BOOK_NOT_FOUND, ex.getMessage());
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse);
    }

    /**
     * 处理BookISBNException异常
     * @param ex 异常
     * @return 响应实体
     */
    @ExceptionHandler(BookISBNException.class)
    public ResponseEntity<ErrorResponse> handleBookISBNException(BookISBNException ex) {
        ErrorResponse errorResponse = new ErrorResponse(BookConstants.BOOK_ISBN_ALREADY_EXISTS, ex.getMessage());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }

    /**
     * 处理BookFieldInvalidException异常
     * @param ex 异常
     * @return 响应实体
     */
    @ExceptionHandler(BookFieldInvalidException.class)
    public ResponseEntity<ErrorResponse> handleBookFieldInvalidException(BookFieldInvalidException ex) {
        ErrorResponse errorResponse = new ErrorResponse(BookConstants.BOOK_FIELD_INVALID, ex.getMessage());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }

    /**
     * 处理BookIdInvalidException异常
     * @param ex 异常
     * @return 响应实体
     */
    @ExceptionHandler(BookIdInvalidException.class)
    public ResponseEntity<ErrorResponse> handleBookIdInvalidException(BookIdInvalidException ex) {
        ErrorResponse errorResponse = new ErrorResponse(BookConstants.BOOK_ID_INVALID, ex.getMessage());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }

}
